home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Utilities / PalmLink / src / PL_SLP.c < prev    next >
C/C++ Source or Header  |  2000-05-05  |  7KB  |  252 lines

  1. /**
  2.  * PalmLink -- Connect 3Com Palm with Amiga
  3.  *
  4.  * SLP (Serial Link Protocol)
  5.  *
  6.  * (C) 1998-2000 Richard Körber <rkoerber@gmx.de>
  7.  *
  8.  *------------------------------------------------------------------
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  *
  24.  * You must not use this source code to gain profit of any kind!
  25.  */
  26.  
  27. #include "palmlink_glob.h"
  28.  
  29.  
  30. /*------------------------------------------------------**
  31. ** Name:        CRC16                            private
  32. **
  33. ** Funktion:    Calculate CRC16 checksum
  34. **
  35. ** Parameter:   buf       Start des Buffers
  36. **              len       Länge des Buffers
  37. **              crc       CRC aus vorigem Bufferabschnitt,
  38. **                        0 beim ersten mal
  39. ** Ergebnis:    CRC-Prüfsumme
  40. //>
  41. ** Bemerkungen:
  42. **
  43. ** Revision:    31. Mai 1998, 22:01:39
  44. */
  45. static UWORD CRC16(UBYTE *buf, UWORD len, UWORD crc)
  46. {
  47.   register UWORD i;
  48.  
  49.   while(len--)
  50.   {
  51.     crc ^= (UWORD)(*buf++ << 8);
  52.     for(i=0; i<8; i++)
  53.     {
  54.       if(crc & 0x8000)
  55.         crc = (crc<<1) ^ 0x1021;
  56.       else
  57.         crc = crc<<1;
  58.     }
  59.   }
  60.   return(crc);
  61. }
  62. //<
  63.  
  64. /*------------------------------------------------------**
  65. ** Name:        PL_SLPWrite                       public
  66. **
  67. ** Funktion:    Verschickt ein SLP-Paket
  68. **
  69. ** Parameter:   socket    Socket für die Übertragung
  70. **              buffer    zu übertragener Puffer
  71. **              length    Länge des Puffers
  72. **              header    SLP-Header
  73. **              PADP      Optional: PADP-Header
  74. ** Ergebnis:    length    Verschickte Daten oder
  75. **                        -1: Fehler
  76. //>
  77. ** Bemerkungen:
  78. **
  79. ** Revision:    31. Mai 1998, 21:14:30
  80. */
  81. __saveds __asm LONG PL_SLPWrite
  82. (
  83.   register __a0 APTR socket,
  84.   register __a1 APTR buffer,
  85.   register __d0 LONG length,
  86.   register __a2 struct PL_SLP_Header *header,
  87.   register __a3 struct PL_PADP_Header *padp
  88. )
  89. {
  90.   struct PL_Socket *sock = (struct PL_Socket *)socket;
  91.   UWORD i;
  92.   UBYTE hdrsum;
  93.   UWORD checksum;
  94.  
  95.   sock->lastError = PLERR_OKAY;
  96.  
  97.   /* Create signature */
  98.   header->signature[0] = 0xBE;
  99.   header->signature[1] = 0xEF;
  100.   header->signature[2] = 0xED;
  101.   header->dataSize     = (padp ? length+sizeof(struct PL_PADP_Header) : length) ;
  102.  
  103.   /* Calculate header checksum */
  104.   for(hdrsum = i = 0; i<(sizeof(struct PL_SLP_Header)-1); i++)
  105.   {
  106.     hdrsum += ((UBYTE *)header)[i];
  107.   }
  108.   header->checksum = hdrsum;
  109.  
  110.   /* Calculate data checksum */
  111.   checksum = CRC16((UBYTE *)header,sizeof(struct PL_SLP_Header),0);
  112.   if(padp) checksum = CRC16((UBYTE *)padp,sizeof(struct PL_PADP_Header),checksum);
  113.   checksum = CRC16((UBYTE *)buffer,length,checksum);
  114.  
  115.   /* Send packet, and we are done */
  116.   if(PL_RawWrite(socket,(UBYTE *)header,sizeof(struct PL_SLP_Header)))
  117.   {
  118.     if(!padp || PL_RawWrite(socket,padp,sizeof(struct PL_PADP_Header)))
  119.     {
  120.       if(PL_RawWrite(socket,buffer,length))
  121.       {
  122.         if(PL_RawWrite(socket,(UBYTE *)&checksum,2))
  123.         {
  124. #ifdef SLPDEBUG
  125.   Printf("SLP A->P: dest=%ld src=%ld type=%ld dataSize=%ld transID=0x%02lx sum=0x%02lx\n",header->destSocket,header->srcSocket,header->pckType,header->dataSize,header->transID,header->checksum);
  126. #endif
  127.           return(length);                 // Success
  128.         }
  129.       }
  130.     }
  131.   }
  132.   return(-1);                           // Failure
  133. }
  134. //<
  135.  
  136. /*------------------------------------------------------**
  137. ** Name:        PL_SLPRead                        public
  138. **
  139. ** Funktion:    Holt ein SLP-Paket
  140. **
  141. ** Parameter:   socket    Socket für die Übertragung
  142. **              buffer    Empfangspuffer
  143. **              length    Länge des Empfangsbuffer
  144. **              header    SLP-Header-Puffer
  145. **              padp      Optional: PADP-Header
  146. ** Ergebnis:    length    Länge des empfangenen Puffers
  147. **                        (ohne SLP-Header), -1: Fehler
  148. //>
  149. ** Bemerkungen:
  150. **
  151. ** Revision:     1. Juni 1998, 16:01:46
  152. */
  153. __saveds __asm LONG PL_SLPRead
  154. (
  155.   register __a0 APTR socket,
  156.   register __a1 APTR buffer,
  157.   register __d0 LONG length,
  158.   register __a2 struct PL_SLP_Header *header,
  159.   register __a3 struct PL_PADP_Header *padp
  160. )
  161. {
  162.   struct PL_Socket *sock = (struct PL_Socket *)socket;
  163.   UBYTE  read;                          // Reading into this variable
  164.   UBYTE  hdrsum;
  165.   UWORD  i;
  166.   UWORD  readChecksum;
  167.   UWORD  checksum;
  168.  
  169.   sock->lastError = PLERR_OKAY;         // No error occured yet
  170.  
  171.   /* State machine: wait for header */
  172.   if(PL_RawRead(socket,&read,1))
  173.   {
  174.     for(;;)
  175.     {
  176.       /* wait for 0xBEEFED */
  177.       if(read==0xBE)
  178.       {
  179.         header->signature[0] = read;
  180.         if(!PL_RawRead(socket,&read,1)) return(-1);   // <--- Failed ---
  181.         if(read!=0xEF) continue;
  182.         header->signature[1] = read;
  183.         if(!PL_RawRead(socket,&read,1)) return(-1);   // <--- Failed ---
  184.         if(read!=0xED) continue;
  185.         header->signature[2] = read;
  186.       }
  187.       else
  188.       {
  189.         if(!PL_RawRead(socket,&read,1)) return(-1);   // <--- Failed ---
  190.         continue;
  191.       }
  192.  
  193.       /* Looks promising, read rest of the header */
  194.       if(!PL_RawRead(socket,&header->destSocket,7)) return(-1); // <--- Failed ---
  195.  
  196.       /* Check sum okay? */
  197.       for(hdrsum = i = 0; i<(sizeof(struct PL_SLP_Header)-1); i++)
  198.       {
  199.         hdrsum += ((UBYTE *)header)[i];
  200.       }
  201.  
  202.       /* LOOP packet ? */
  203.       if(header->pckType == PLSLPTYPE_LOOP)           // is ignored
  204.       {
  205.         for(i=0; i<(header->dataSize+2); i++)
  206.         {
  207.           if(!PL_RawRead(socket,&read,1)) return(-1); // <--- Failure ---
  208.         }
  209.         continue;                                     // Wait for next packet
  210.       }
  211.  
  212.       if(header->checksum == hdrsum) break;           // Found a good header
  213.     }
  214.   }
  215.  
  216.   /* Fetch rest of data */
  217.   if(padp)
  218.   {
  219.     length = min(header->dataSize - sizeof(struct PL_PADP_Header), length);
  220.     if(!PL_RawRead(socket,padp,sizeof(struct PL_PADP_Header))) return(-1);
  221.     if(!PL_RawRead(socket,buffer,length)) return(-1);   // Read error
  222.   }
  223.   else
  224.   {
  225.     length = min(header->dataSize,length);
  226.     if(!PL_RawRead(socket,buffer,length)) return(-1);   // read error
  227.   }
  228.  
  229.   /* Read CRC16 */
  230.   if(!PL_RawRead(socket,(UBYTE *)&readChecksum,2)) return(-1); // read error
  231.  
  232.   /* Compare data checksum */
  233.   checksum = CRC16((UBYTE *)header,sizeof(struct PL_SLP_Header),0);
  234.   if(padp) checksum = CRC16((UBYTE *)padp,sizeof(struct PL_PADP_Header),checksum);
  235.   checksum = CRC16((UBYTE *)buffer,length,checksum);
  236.   if(checksum!=readChecksum)
  237.   {
  238.     sock->lastError = PLERR_CHECKSUM;
  239.     return(-1);                                       // bad checksum
  240.   }
  241.  
  242. #ifdef SLPDEBUG
  243.   Printf("SLP A<-P: dest=%ld src=%ld type=%ld dataSize=%ld transID=0x%02lx sum=0x%02lx\n",header->destSocket,header->srcSocket,header->pckType,header->dataSize,header->transID,header->checksum);
  244. #endif
  245.  
  246.   return(length);                                     // Packet received
  247. }
  248. //<
  249.  
  250.  
  251. /********************************************************************/
  252.